LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity lcd_driver is
  port (clk : in std_logic;
		rstn : in std_logic;
		hsync : in std_logic;
		vcounter : in integer;
		data : out std_logic_vector(7 downto 0);
		h_address : out std_logic_vector(8 downto 0);
		hsync_out : out std_logic;
		r_in : in std_logic_vector(7 downto 0);
		g_in : in std_logic_vector(7 downto 0);
		b_in : in std_logic_vector(7 downto 0));
end entity;

architecture rtl of lcd_driver is
  signal hcounter : integer;
  signal skipped_hsync : std_logic;
begin
	process (rstn, clk, hsync)
	begin
		if rstn = '0' then
			hcounter <= 0;
		else
			if rising_edge(clk) then
				if hsync = '0' then
					if skipped_hsync = '1' then
						hcounter <= 0;
						skipped_hsync <= '0';
					else 
						skipped_hsync <= '1';
						hcounter <= hcounter + 1;
					end if;
				else
					hcounter <= hcounter + 1;
				end if;
			end if;
		end if;
	end process;
	
	process(hcounter)
	begin
		h_address <= std_logic_vector(to_unsigned((hcounter - 240) / 4, 9));
	end process;
			
	process (hcounter)
	begin
		if hcounter = 0 then
			hsync_out <= '0';
		else
			hsync_out <= '1';
		end if;
	end process;

	process (hcounter, vcounter, r_in, g_in, b_in)
	begin
		if (hcounter >= 240 and
			hcounter < 1520 and
			vcounter >= 42 and
			vcounter < 523) then
			if (vcounter mod 4 = 0 or
				vcounter mod 4 = 3) then
				case hcounter mod 4 is
				when 0 => data <= r_in;
				when 1 => data <= g_in;
				when 2 => data <= b_in;
				when others => data <= "00000000";
				end case;
			else
				case hcounter mod 4 is
				when 0 => data <= b_in;
				when 1 => data <= r_in;
				when 2 => data <= g_in;
				when others => data <= "00000000";
				end case;
			end if;
		else
			data <= "00000000";
		end if;
	end process;
end rtl;

